home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Format CD 42
/
Amiga Format AFCD42 (Issue 126, Aug 1999).iso
/
-serious-
/
comms
/
other
/
micq-0.4.0
/
nonblkout.c
< prev
next >
Wrap
C/C++ Source or Header
|
1999-05-14
|
3KB
|
143 lines
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <dos/dos.h>
#include <proto/dos.h>
#include <proto/exec.h>
#define bufsize 16384
#define linesize 1024
char outbufque[bufsize];
char *outbufwptr=outbufque,*outbufrptr=outbufque,*outbufnrptr=outbufque;
struct FileHandle *outfilehandle=NULL;
struct StandardPacket *dospacket=NULL;
struct MsgPort *dosport=NULL;
struct FileHandle *outputfilehandle=NULL;
void addchartobuf(char c);
void addstrtobuf(char *s, int l);
void cleanoutbuf(void);
int initoutbuf(void);
void writeoutbufout(void);
void outbufprintf(char *template, ...);
void cleanoutbuf()
{
if (dospacket && dospacket->sp_Msg.mn_Node.ln_Succ!=NULL)
{
AbortPkt(dosport,&dospacket->sp_Pkt);
while (GetMsg(dosport)==NULL)
WaitPort(dosport);
while (GetMsg(dosport));
}
if (dospacket) FreeDosObject(DOS_STDPKT,(char *)dospacket+sizeof(dospacket->sp_Msg));
if (dosport) DeleteMsgPort(dosport);
}
int initoutbuf()
{
BPTR so;
if (outputfilehandle) return -1;
if ((so=Output())==NULL) return -2;
outputfilehandle=(struct FileHandle *)(((int)so)<<2);
if ((dospacket=(struct StandardPacket *)AllocDosObject(DOS_STDPKT,NULL))==NULL) return -3;
dospacket=(char *)dospacket-sizeof(dospacket->sp_Msg);
dospacket->sp_Msg.mn_Node.ln_Succ=NULL;
dospacket->sp_Msg.mn_Node.ln_Name=(char *)&dospacket->sp_Pkt;
dospacket->sp_Pkt.dp_Link=&dospacket->sp_Msg;
atexit(cleanoutbuf);
if ((dosport=CreateMsgPort())==NULL) return -4;
return 0;
}
void addchartobuf(char c)
{
if (outbufrptr-1==outbufwptr || (outbufrptr==outbufque && outbufwptr==outbufque+bufsize-1)) return;
*outbufwptr++=c;
if (outbufwptr>=outbufque+bufsize) outbufwptr=outbufque;
}
void addstrtobuf(char *s, int sl)
{
int l,r;
if (sl==0) return;
r=outbufrptr-outbufwptr-1;
if (r==0) return;
else if (r<0) r=bufsize-r-2;
if (r>sl) l=sl; else l=r;
if ((outbufwptr-outbufque+l)<bufsize)
{
memcpy(outbufwptr,s,l);
outbufwptr+=l;
}
else
{
r=outbufque+bufsize-outbufwptr;
if (r)
{
memcpy(outbufwptr,s,r);
l=l-r;
}
outbufwptr=outbufque;
if (l)
{
outbufwptr=outbufque;
memcpy(outbufwptr,s+r,l);
outbufwptr+=l;
}
}
}
void writeoutbufout()
{
if (dospacket->sp_Msg.mn_Node.ln_Succ==NULL || GetMsg(dosport)==&(dospacket->sp_Msg))
{
if (dospacket->sp_Msg.mn_Node.ln_Succ!=NULL)
{
dospacket->sp_Msg.mn_Node.ln_Succ=NULL;
outbufrptr=outbufnrptr;
}
if (outbufrptr==outbufwptr) return;
if (outbufwptr<outbufrptr)
{
outbufnrptr=outbufque;
dospacket->sp_Pkt.dp_Arg3=outbufque+bufsize-outbufrptr;
}
else
{
outbufnrptr=outbufwptr;
dospacket->sp_Pkt.dp_Arg3=outbufwptr-outbufrptr;
}
dospacket->sp_Pkt.dp_Action=ACTION_WRITE;
dospacket->sp_Pkt.dp_Arg1=outputfilehandle->fh_Arg1;
dospacket->sp_Pkt.dp_Arg2=(int)outbufrptr;
SendPkt(&(dospacket->sp_Pkt),outputfilehandle->fh_Type,dosport);
}
return;
}
void outbufprintf(char *template, ...)
{
char linebuf[linesize];
va_list args;
if (dospacket==NULL) return;
va_start(args,template);
vsprintf( linebuf, template, args );
addstrtobuf(linebuf,strlen(linebuf));
writeoutbufout();
va_end(args);
}